﻿using Ldt.DataEngine.RuleAssemble;
using LdtDataEngin.ModuleDetail.BaseModule.Optimization;
using LdtDataEngin.ModuleDetail.BaseModule.PersonnelBase;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.MoneyAssemble;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.Data;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.CommonManageModel;
using LdtJudge.DataEngine.Model.Personnel;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.OptimizationModule.JointEntrustedAgent
{
    /// <summary>
    /// 共同委托代理人处理模块
    /// </summary>
    /// <seealso cref="LdtDataEngin.ModuleDetail.BaseModule.Optimization.OptimizationBase" />
    public class JointEntrustedAgent : OptimizationBase
    {
        /// <summary>
        /// 人员转换
        /// </summary>
        private PersonnelAnalysisBase personnelAnalysis = new PersonnelAnalysisBase();

        private XmlUtilCommon xmlUtilCommon;
        public JointEntrustedAgent(DataContext dataContextIn, string moudleName)
        {
            dataContext = dataContextIn;
            base.ModuleName = moudleName;
            xmlUtilCommon = new XmlUtilCommon() { dataContext = dataContext };
        }

        /// <summary>
        /// 开始提取        
        /// </summary>
        /// <param name="Name">模块名称</param>
        public void Extrat()
        {
            List<DataModel> ViewSourdatModleList = new List<DataModel>();
            ViewSourdatModleList =
                Newtonsoft.Json.JsonConvert.DeserializeObject<List<DataModel>>(Newtonsoft.Json.JsonConvert.SerializeObject(dataContext.DataLayerOpt.SourdatModleList));
            var configModel = dataContext.DataLayerSys.GetConfigModel(ModuleName);
            configModel = configModel.ConfigDetail?.Where(x => x.Code == "jointentrustedagent").FirstOrDefault();
            personnelAnalysis = new PersonnelAnalysisBase() { spokenamelist = dataContext.DataLayerAns.ElementSpokeList };
            // c.ConfigContent = "";
            //configModel.ConfigContent = System.IO.File.ReadAllText(@$"E:\00工作内容\底层服务\委托代理人\配置Xml\jointentrustedagentTest.xml");
            if (configModel.ConfigContent != null)
            {
                //加载配置文件
                XmlDocument xmlConfig = new XmlDocument();
                xmlConfig.LoadXml(configModel.ConfigContent);
                string xpath = $"root/casetype";
                XmlNodeList caseTypeNodeList = xmlConfig.SelectNodes(xpath);
                if (caseTypeNodeList.Count > 0)
                {
                    XmlNode caseTypeNode = null;
                    foreach (XmlNode x in caseTypeNodeList)
                    {
                        if (x.Attributes["code"].Value.Split(",").Where(x => x == dataContext.DataLayerOpt.CaseType).Any())
                        { caseTypeNode = x; }
                    }
                    if (caseTypeNode == null)
                    {
                        throw (new Exception($"{ModuleName}：提取共同委托代理人，配置错误，找不到【{xpath}】指定类型的{dataContext.DataLayerOpt.CaseType}的节点"));
                    }
                    XmlNodeList originalNodeList = caseTypeNode.SelectNodes("agent/original");
                    if (originalNodeList.Count > 0)
                    {
                        foreach (XmlNode orginal in originalNodeList)
                        {
                            //代理人路径
                            string agentXpath = orginal.Attributes["xpath"].Value;
                            dataContext.InteractiveShow.LogShow("开始读取共同代理人信息：" + agentXpath);
                            List<DataModel> agentList = XmlUtility.ConditionDataModelList(ViewSourdatModleList, "", agentXpath);
                            List<DataModel> appendList = new List<DataModel>();
                            if (agentList != null && agentList.Count > 0)
                            {
                                //开始遍历代理人员
                                foreach (DataModel agent in agentList)
                                {
                                    //读取 代理范围 原文内容
                                    string agentSourceTxt = "";
                                    //可以直接赋值@
                                    if (!agentSourceTxt.Contains("@")) { agentSourceTxt += "@"; }
                                    agentSourceTxt = getAttributeValue(agentXpath.Substring(agentXpath.IndexOf("@") + 1).Replace("]", ""), agent);
                                    if (agentSourceTxt.Contains("以上"))
                                    {
                                        List<ElementSpokeName> personList = personnelAnalysis.GetMatchSpokeManByagentSourceTxt(dataContext.DataLayerAns.ElementSpokeList, ViewSourdatModleList, agentSourceTxt, agent);
                                        if (personList != null && personList.Count > 0)
                                        {
                                            XmlNode party = caseTypeNode.SelectSingleNode("agent/party");
                                            //添加节点
                                            AddJoinAgentList(appendList, personList, agent, party);
                                        }
                                        else
                                        {
                                            dataContext.InteractiveShow.LogShow($"无法从【{agentSourceTxt}】中提取到人员信息");
                                        }
                                    }
                                    else
                                    {
                                        //调用正则
                                        string rgexNo = orginal.Attributes["substitutionreg"].Value;
                                        List<string> listvalue = new List<string>();
                                        SqlCmmCommon sqlCmm = new SqlCmmCommon("LdtCommonManage");
                                        List<RuleInfoUnit> dt = sqlCmm.GetRiuIDbyRiuCode(rgexNo);
                                        string riuID = dt[0].RIU_ID.ToString();
                                        string cnReg = RuleParseClass.GerParseReg(riuID)[0];
                                        if (cnReg.IndexOf("@{Name}") > -1)
                                        {
                                            string regvalue = "";
                                            if (dataContext.DataLayerAns.ElementSpokeList.Count > 0)
                                            {
                                                foreach (var spoke in dataContext.DataLayerAns.ElementSpokeList)
                                                {
                                                    if (regvalue == "")
                                                    {
                                                        regvalue = spoke.ES_FullName;
                                                    }
                                                    else
                                                    {
                                                        regvalue = regvalue + "|" + spoke.ES_FullName;
                                                    }
                                                }

                                            }
                                            cnReg = cnReg.Replace("@{Name}", regvalue);
                                            MatchCollection matchArr = Regex.Matches(agentSourceTxt, cnReg);
                                            foreach (Match mach in matchArr)
                                            {
                                                listvalue.Add(mach.Value);
                                            }
                                        }
                                        else
                                        {
                                            listvalue = RuleParseClass.GetParseRegCodeList(rgexNo, agentSourceTxt);
                                        }
                                        if (listvalue != null && listvalue.Count > 0)
                                        {
                                            foreach (string exPressResult in listvalue)
                                            {

                                                //获取原告节点
                                                //调用小强方法实现
                                                List<ElementSpokeName> personList = personnelAnalysis.GetMatchSpokeManByRoleName(dataContext.DataLayerAns.ElementSpokeList, exPressResult).ToList();
                                                if (personList != null && personList.Count > 0)
                                                {
                                                    XmlNode party = caseTypeNode.SelectSingleNode("agent/party");
                                                    //添加节点
                                                    AddJoinAgentList(appendList, personList, agent, party);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            dataContext.InteractiveShow.LogShow($"正则{rgexNo},无法从【{agentSourceTxt}】中提取到内容");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                dataContext.InteractiveShow.LogShow("不存在共同代理人信息：" + agentXpath);
                            }
                        }
                        dataContext.DataLayerOpt.OptimizationXml = XmlUtility.DataModelByXml(dataContext.DataLayerOpt.SourdatModleList);
                    }
                    else
                    {
                        throw (new Exception($"{ModuleName}：提取共同委托代理人，配置错误，找不到【{xpath}/agent/original】节点"));
                    }
                }
                else
                {
                    throw (new Exception($"{ModuleName}：提取共同委托代理人，配置错误，找不到【casetype】节点"));
                }
            }
        }

        /// <summary>
        /// 获取 属性值
        /// </summary>
        /// <param name="attrName">Name of the attribute.</param>
        /// <param name="d">节点</param>
        /// <returns></returns>
        public string getAttributeValue(string attrName, DataModel d)
        {
            AttributeInfo atr = d.AttributesList.Where(x => x.Name.Trim() == attrName).FirstOrDefault();
            return atr?.sourceList[0]?.SaveValue;
        }
        /// <summary>
        /// Adds the join agent list.
        /// </summary>
        /// <param name="appendList">需要新增的节点结果集</param>
        /// <param name="personNode">需要新增节点的诉讼参与人集合</param>
        /// <param name="agent">共同代理人</param>
        /// <param name="party">配置项</param>
        public void AddJoinAgentList(List<DataModel> appendList, List<ElementSpokeName> personNode, DataModel agent, XmlNode party)
        {
            if (personNode != null && personNode.Count > 0)
            {
                foreach (ElementSpokeName parentNode in personNode)
                {
                    string xpath = party.Attributes["xpath"].Value;//添加节点位置
                    xpath = xpath.Replace("suitpartName", parentNode.ES_FullName);
                    //string parentId = parentNode.ES_ID;

                    xmlUtilCommon.CaseNodeUpdate(dataContext.DataLayerOpt.SourdatModleList, xpath);
                    List<DataModel> hasAgent = XmlUtility.ConditionDataModelList(dataContext.DataLayerOpt.SourdatModleList, "", xpath);
                    if (hasAgent != null && hasAgent.Count > 0)
                    {
                        //节点已经存在直接添加属性
                        hasAgent.ForEach(x => AddAttribute(x, agent, party, dataContext.DataLayerOpt.SourdatModleList));
                    }
                    else
                    {
                        dataContext.InteractiveShow.LogShow("读取不到节点：" + xpath);
                    }
                }

            }
        }
        /// <summary>
        /// Adds the data model. 程序算法：先找到根节点，然后从根节点开始一级一级添加
        /// </summary>
        /// <param name="appendList">The append list.</param>
        /// <param name="xPath">The x path.</param>
        /// <param name="attrName">Name of the attribute.</param>
        /// <param name="attrValue">The attribute value.</param>
        /// <param name="parengId">The pareng identifier.</param>
        /// <param name="rootId">The root identifier.</param>
        /// <param name="level">The level.</param>
        public void AddDataModel(List<DataModel> appendList, string xPath, string rootId)
        {
            //根节点路径
            string rootPath = dataContext.DataLayerOpt.SourdatModleList.Where(x => x.ID == rootId).FirstOrDefault().XmlPath;
            string tempPath = xPath.Replace(rootPath, "");
            rootPath = rootPath + tempPath.Substring(0, tempPath.IndexOf("/"));//添加Xpath路径中的属性            
            string[] xPathString = tempPath.Substring(tempPath.IndexOf("/") + 1).Split("/");
            tempPath = rootPath;
            foreach (string noddPath in xPathString)
            {
                tempPath = tempPath + "/" + noddPath;
                string id = Snowflake.Instance().GetId().ToString();

                DataModel a = new DataModel
                {
                    ID = id,
                    ParentId = rootId,
                    XmlPath = tempPath,
                    AttributesList = new List<AttributeInfo>()
                };

                appendList.Add(a);

                rootId = id;
            }
        }

        /// <summary>
        /// 添加party中 属性到节点 desNode
        /// </summary>
        /// <param name="desNode">需要添加的共同委托代理人ID的节点.</param>
        /// <param name="agent">代理人信息.</param>
        /// <param name="party">配置信息.</param>
        public void AddAttribute(DataModel desNode, DataModel agent, XmlNode party,List<DataModel> dataModelList)
        {
            //添加属性
            foreach (XmlNode agentAttrNode in party.ChildNodes)
            {
                string attrName = agentAttrNode.Attributes["name"].Value;//属性名
                string attrValueName = agentAttrNode.Attributes["attributeValue"].Value;//属性内容路径

                string attrValue = agent.ID;
                if (attrValueName != "id")
                {
                    attrValue = agent.AttributesList.Where(x => x.Name == attrName).FirstOrDefault()?.sourceList?[0].SaveValue;
                }

                if (desNode.AttributesList == null) { desNode.AttributesList = new List<AttributeInfo>(); }
                if (desNode.AttributesList.Where(x => x.Name == attrName).Any())
                {
                    //添加逻辑：如果给委托诉讼代理人添加共同代理人只能添加自身的Id
                    //给当事人首次添加时判断是否有代理人，如果没有直接添加
                    //再次给当事人添加共同代理人时，如果集合中没有该代理人ID的详情则可以添加，
                    //否则新建一个代理人信息添加到集合中即可，当前节点不做操作
                    var attributesLists = desNode.AttributesList.Where(x => x.Name == attrName).ToList();
                    bool cz = false;
                    foreach (var x in attributesLists)
                    {
                        if (x.sourceList.Where(y => y.SaveValue == attrValue).Any())
                        {
                            cz = true;
                            break;
                        }
                    }
                    if (!cz)
                    {
                        if (desNode.AttributesList.FirstOrDefault(x => x.Name == "诉讼地位")?.sourceList.FirstOrDefault(u => u.ExtValue == "委托诉讼代理人") != null)
                        {
                            continue;
                        }
                        else
                        {
                            if (dataModelList.Any(x => x.XmlPath == desNode.XmlPath && x.AttributesList.Any(y => y.sourceList.Any(z => z.SaveValue == attrValue))&&x.ParentId== desNode.ParentId))
                            {
                                continue;
                            }
                            else
                            {
                                AttributeInfo attr = new AttributeInfo
                                {
                                    Name = attrName,
                                    sourceList = new List<Source>()
                                };
                                attr.sourceList.Add(new Source { IsCheck = "1", SaveValue = attrValue });
                                //desNode.AttributesList.Add(attr);
                                DataModel dataModel = new DataModel();
                                dataModel.ParentId = desNode.ParentId;
                                dataModel.XmlPath = desNode.XmlPath;
                                dataModel.sourceData = dataModel.sourceData;
                                dataModel.AttributesList = new List<AttributeInfo>() { attr };
                                dataModel.ID = Snowflake.Instance().GetId().ToString();
                                dataModelList.Add(dataModel);
                            }
                        }
                    }
                }
                else
                {
                    if (desNode.AttributesList.FirstOrDefault(x => x.Name == "诉讼地位")?.sourceList.FirstOrDefault(u => u.ExtValue == "委托诉讼代理人") != null)
                    {
                        if (desNode.ID == agent.ID)
                        {
                            AttributeInfo attr = new AttributeInfo
                            {
                                Name = attrName,
                                sourceList = new List<Source>()
                            };
                            attr.sourceList.Add(new Source { IsCheck = "1", SaveValue = attrValue });
                            desNode.AttributesList.Add(attr);
                        }
                    }
                    else
                    {
                        AttributeInfo attr = new AttributeInfo
                        {
                            Name = attrName,
                            sourceList = new List<Source>()
                        };
                        attr.sourceList.Add(new Source { IsCheck = "1", SaveValue = attrValue });
                        desNode.AttributesList.Add(attr);
                    }
                }
            }
        }
    }
}
